/*
 *    Copyright (c) 2018-2025, lengleng All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution.
 * Neither the name of the pig4cloud.com developer nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 * Author: lengleng (wangiegie@gmail.com)
 */
package cn.s1995.sloth.bizs.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.s1995.sloth.bizs.constant.RedisKeyCst;
import cn.s1995.sloth.bizs.entity.RegionData;
import cn.s1995.sloth.bizs.mapper.RegionDataMapper;
import cn.s1995.sloth.bizs.oo.vo.PCDTreeVO;
import cn.s1995.sloth.bizs.service.RegionDataService;
import cn.s1995.sloth.bizs.util.RedisUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 地区表
 *
 * @author penf
 * @date 2022-03-01 15:58:59
 */
@Service
@RequiredArgsConstructor
public class RegionDataServiceImpl extends ServiceImpl<RegionDataMapper, RegionData> implements RegionDataService {

    private final RedisUtil redisUtil;

    @Override
    public List<PCDTreeVO> getTree(Set<Integer> levelList) {
        List<RegionData> list;
        Object o = redisUtil.get(RedisKeyCst.REGION);
        if (o != null) {
            list = (List<RegionData>) o;
        } else {
            list = this.list(
                    Wrappers.<RegionData>lambdaQuery().select(
                            RegionData::getId,
                            RegionData::getParentId,
                            RegionData::getLevelType,
                            RegionData::getName,
                            RegionData::getLng,
                            RegionData::getLat
                    )

            );
            redisUtil.set(RedisKeyCst.REGION, list);
        }

        if (CollectionUtil.isNotEmpty(levelList)) {
            list = list.stream().filter(item -> levelList.contains(item.getLevelType())).collect(Collectors.toList());
        }

        // 构建树形数据
        List<RegionData> finalList = list;
        List<PCDTreeVO> collect = list.stream()
                .filter(item -> item.getParentId().equals(0L))
                .map(m -> {
                    PCDTreeVO vo = PCDTreeVO.builder()
                            .value(m.getId().toString())
                            .label(m.getName())
                            .lng(m.getLng())
                            .lat(m.getLat())
                            .children(getChildren(finalList, m.getId().toString()))
                            .build();
                    return vo;
                }).collect(Collectors.toList());

        return collect;
    }

    /**
     * 获取子节点数据
     *
     * @param list
     * @param pId
     * @return
     */
    private List<PCDTreeVO> getChildren(List<RegionData> list, String pId) {
        // 子类
        List<PCDTreeVO> children = list.stream().filter(x -> x.getParentId().toString().equals(pId))
                .map(m -> {
                    PCDTreeVO vo = PCDTreeVO.builder()
                            .value(m.getId().toString())
                            .label(m.getName())
                            .lng(m.getLng())
                            .lat(m.getLat())
                            .build();
                    return vo;
                }).collect(Collectors.toList());
        if (CollectionUtil.isEmpty(children)) {
            return new ArrayList<>();
        }
        // 后辈中的非子类
        List<RegionData> successor = list.stream().filter(x -> !x.getParentId().toString().equals(pId)).collect(Collectors.toList());
        children.forEach(item -> item.setChildren(getChildren(successor, item.getValue())));
        return children;
    }

}
